﻿/**
  ******************************************************************************
  * @file    Libraries/Device/JS32T031/JS32T031_LL_Driver/src/js32t031_ll_timer.c
  * @author  JUSHENG Application Team
  * @version V1.0.0
  * @date    02-19-2022
  * @brief   This file contains all the TIMER LL firmware functions.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2022 JUSHENG</center></h2>
  *
  *
  ******************************************************************************
  */ 

/* Includes ------------------------------------------------------------------*/
#include "include.h"

/** @addtogroup JS32T031_StdPeriph_Driver JS32T031 Driver
  * @{
  */
  
/** @defgroup timer_interface_gr TIMER Driver
  * @ingroup  JS32T031_StdPeriph_Driver
  * @{
  */

/** @addtogroup TIMER_LL_Driver TIMER LL Driver
  * @ingroup  timer_interface_gr
  * @{
  */
  
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
#define TIME_TRIM_ADDR  0x1FF01234

/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/** @defgroup TIMER_LL_Inti_Cfg TIMER LL Initialization And Configuration
  * @ingroup  TIMER_LL_Driver
  * @brief    TIMER LL Initialization And Configuration
  * @{
  */

/**
  * @brief  Low layer timer init function
  * @param  p_timer: Set to division and source colock of TIMERx
  * @param  p_init : Configure the p_timer initialization structure
  * @retval None
  */
void ll_timer_init(TIMER_TypeDef *p_timer, TYPE_LL_TIMER_INIT *p_init)
{
    u32 tmr_con;
    p_timer->TMR_CAP1 = 0x0000;
    p_timer->TMR_CAP3 = 0x0000;
    
    tmr_con = p_timer->TMR_CON;
    tmr_con = (tmr_con & (~LL_TIMER_CON_DIVISION_SET(ALL_WORD_FF))) | LL_TIMER_CON_DIVISION_SET(p_init->prescaler);
    tmr_con = (tmr_con & (~LL_TIMER_CON_SRC_SEL(ALL_WORD_FF))) | LL_TIMER_CON_SRC_SEL(p_init->timer_src_sel);
    p_timer->TMR_CON = tmr_con;
}

/**
  * @brief  Low layer timer disable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_stop(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_CLR |= LL_TIMER_CLR_ALL_PENDING;
    p_timer->TMR_EN &= ~LL_TIMER_EN;
}

/**
  * @brief  Low layer timer start function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_start(TIMER_TypeDef *p_timer, TYPE_ENUM_LL_TIMER_MODE_SEL mode_sel)
{
    u32 cnt_con = p_timer->TMR_CON;
    cnt_con = (cnt_con & (~LL_TIMER_CON_MODE_SET(ALL_WORD_FF))) | LL_TIMER_CON_MODE_SET(mode_sel);
    p_timer->TMR_CON = cnt_con;

    p_timer->TMR_CLR |= LL_TIMER_CLR_ALL_PENDING;

    p_timer->TMR_EN |= LL_TIMER_EN;
}

/**
  * @brief  Low layer timer cnt set
  * @param  p_timer  : Structure pointer set to TIMERx
  * @param  cnt_set  : timer cnt value(timer0~timer2 16bits cnt value, timer4 32bits cnt value)
  * @retval None
  */
void ll_timer_cnt_set(TIMER_TypeDef *p_timer, u32 cnt_set)
{
    if(TIMER4 == p_timer)
    {
        p_timer->TMR_CNT = cnt_set;
    }
    else
    {
        p_timer->TMR_CNT = (u16)cnt_set;
    }
}

/**
  * @brief  Low layer timer cnt get
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval timer cnt value(timer0~timer2 16bits cnt value, timer4 32bits cnt value)
  */
u32 ll_timer_cnt_get(TIMER_TypeDef *p_timer)
{
    return (p_timer->TMR_CNT);
}

/**
  * @brief  set timer to count mode
  * @param  p_timer  : Structure pointer set to TIMERx
  * @param  cnt_cfg  : Structure pointer set to TIMERx counter mode
  * @retval None
  */
void ll_timer_cnt_mode_config(TIMER_TypeDef *p_timer, TYPE_LL_TIMER_CNT_CFG *cnt_cfg)
{
    p_timer->TMR_CNT  = cnt_cfg->count_initial;
    p_timer->TMR_CAP1 = cnt_cfg->count_period;
    
    p_timer->TMR_CAP3 = cnt_cfg->count_period | ((0 << 16) & 0xFFFF0000);

    if(cnt_cfg->count_ie)
    {
        p_timer->TMR_IE |= LL_TIMER_IE_CNT_PRD_IE;
    }
    else
    {
        p_timer->TMR_IE &= ~LL_TIMER_IE_CNT_PRD_IE;
    }
    p_timer->TMR_CLR |= LL_TIMER_CLR_CNT_PRD_PENDING | LL_TIMER_CLR_CNT_OVERFLOW_PENDING;
}

/**
  * @brief  set timer to pwm mode
  * @param  p_timer  : Structure pointer set to TIMERx
  * @param  upper_limit  : Upper limit value
  * @param  lower_limit  : Lower limit value
  * @retval None Upper
  */
void ll_timer_dir_pin_limit_value(TIMER_TypeDef *p_timer, u32 upper_limit, u32 lower_limit)
{
    p_timer->TMR_CNT  = 0;
    p_timer->TMR_CAP1 = upper_limit;
    p_timer->TMR_CAP2 = lower_limit;
}

/**
  * @brief  set timer to pwm mode
  * @param  p_timer  : Structure pointer set to TIMERx
  * @param  pwm_cfg  : Structure pointer set to TIMERx pwm mode
  * @retval None
  */
void ll_timer_pwm_mode_config(TIMER_TypeDef *p_timer, TYPE_LL_TIMER_PWM_CFG *pwm_cfg)
{
    p_timer->TMR_CNT  = 0;
    p_timer->TMR_CAP1 = pwm_cfg->pwm_period;
    p_timer->TMR_CAP2 = pwm_cfg->pwm_duty;
    
    p_timer->TMR_CAP3 = pwm_cfg->pwm_period | ((pwm_cfg->pwm_duty << 16) & 0xFFFF0000);
}

/**
  * @brief  set timer to capture mode
  * @param  p_timer  : Structure pointer set to TIMERx
  * @param  cap_cfg  : Structure pointer set to TIMERx capture mode
  * @retval None
  */
void ll_timer_cap_mode_config(TIMER_TypeDef *p_timer, TYPE_LL_TIMER_CAP_CFG *cap_cfg)
{
    u32 cap_con = 0;
    p_timer->TMR_CNT  = 0;
    p_timer->TMR_CAP1 = 0;
    p_timer->TMR_CAP2 = 0;

    cap_con = p_timer->TMR_CON;

    //cap 
    if(cap_cfg->cap1_pol_sel == LL_TIMER_CAP_POL_FALLING)
    {
        cap_con |= LL_TIMER_CON_CAP1_POL;
    }
    if(cap_cfg->cap2_pol_sel == LL_TIMER_CAP_POL_FALLING)
    {
        cap_con |= LL_TIMER_CON_CAP2_POL;
    }
    //reset config
    if(cap_cfg->cap1_reset)
    {
        cap_con |= LL_TIMER_CON_CAP1_CNT_RESET;
    }
    if(cap_cfg->cap2_reset)
    {
        cap_con |= LL_TIMER_CON_CAP2_CNT_RESET;
    }
    //mode config
    if(cap_cfg->cap_mode)
    {
        cap_con |= LL_TIMER_CON_CAP_REGISTER_CNT;
    }
    else
    {
        cap_con &= ~(LL_TIMER_CON_CAP_REGISTER_CNT);
    }
    
    // ie config
    if(cap_cfg->cap1_ie)
    {
        p_timer->TMR_IE |= LL_TIMER_IE_CAPTURE1_IE;
    }
    else
    {
        p_timer->TMR_IE &= ~LL_TIMER_IE_CAPTURE1_IE;
    }

    if(cap_cfg->cap_mode)
    {
        if(cap_cfg->cap2_ie)
        {
            p_timer->TMR_IE |= LL_TIMER_IE_CAPTURE2_IE;
        }
        else
        {
            p_timer->TMR_IE &= ~LL_TIMER_IE_CAPTURE2_IE;
        }
    }
    
    if(cap_cfg->cap_overflow)
    {
        p_timer->TMR_IE |= LL_TIMER_IE_CNT_OVERFLOW_IE;
    }
    else
    {
        p_timer->TMR_IE &= ~LL_TIMER_IE_CNT_OVERFLOW_IE;
    }
    
    
    p_timer->TMR_CON = cap_con;
}

/**
  * @brief  Low layer TIMERx to get the capture_1 count value
  * @param  p_timer   : Structure pointer set to TIMERx
  * @retval None
  */
u16 ll_timer_cap_cap1_get(TIMER_TypeDef *p_timer)
{
    return p_timer->TMR_CAP1;
}

/**
  * @brief  Low layer TIMERx to get the capture_2 count value
  * @param  p_timer   : Structure pointer set to TIMERx
  * @retval None
  */
u16 ll_timer_cap_cap2_get(TIMER_TypeDef *p_timer)
{
    return p_timer->TMR_CAP2;
}

/**
  * @brief  Low layer TIMERx synchronization signal selection 
  * @param  p_timer   : Structure pointer set to TIMERx
  * @param  synco_sel : TYPE_ENUM_LL_TIMER_SYNCO_SEL
  * @retval None
  */
void ll_timer_synco_sel_set(TIMER_TypeDef *p_timer, TYPE_ENUM_LL_TIMER_SYNCO_SEL synco_sel)
{
     p_timer->TMR_CON = ( p_timer->TMR_CON & (~LL_TIMER_CON_SYNCO_SEL(ALL_WORD_FF))) | LL_TIMER_CON_SYNCO_SEL(synco_sel);
}

/**
  * @brief  Low layer TIMERx Synci MODE selection 
  * @param  p_timer    : Structure pointer set to TIMERx
  * @param  slave_mode : TYPE_ENUM_LL_TIMER_SLAVE_MODE
  * @retval None
  */
void ll_timer_slave_mode_set(TIMER_TypeDef *p_timer, TYPE_ENUM_LL_TIMER_SLAVE_MODE slave_mode)
{

     p_timer->TMR_CON = ( p_timer->TMR_CON & (~LL_TIMER_CON_SLAVE_MODE(ALL_WORD_FF))) | LL_TIMER_CON_SLAVE_MODE(slave_mode);
}

/**
  * @brief  Low layer TIMER ALL Sync register set 
  * @param  p_timer    : Structure pointer set to TIMER_ALL
  * @param  data : TIMER0, TIMER1, TIMER2 clear cnt or kick start
  * @retval None
  */
void ll_timer_all_sync_mode_set(TIMER_ALL_TypeDef *p_timer, u32 data)
{
     p_timer->TMR_ALLCON = data;
}

/**
  * @brief  Low layer TIMERx Synci polarity reversed enabled function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_synci_pol_enable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_CON |= LL_TIMER_CON_SYNCI_POL;
}

/**
  * @brief  Low layer TIMERx Synci polarity reversed disable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_synci_pol_disable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_CON &= (~LL_TIMER_CON_SYNCI_POL);
}

/**
  * @brief  Low layer TIMERx enabled function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_enable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_EN |= LL_TIMER_EN;
}

/**
  * @brief  Low layer TIMERx disable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_disable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_EN &= (~LL_TIMER_EN);
}

/**
  * @brief  Low layer Slave mode trigger mode or reset mode interrupt enable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_slave_mode_interrupt_enable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_IE |= LL_TIMER_IE_SLAVE_MOED_IE;
}

/**
  * @brief  Low layer Slave mode trigger mode or reset mode interrupt disable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_slave_mode_interrupt_disable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_IE &= (~LL_TIMER_IE_SLAVE_MOED_IE);
}

/**
  * @brief  Low layer CNT value = CMP value interrupt enable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_cnt_cmp_interrupt_enable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_IE |= LL_TIMER_IE_CNT_CMP_IE;
}

/**
  * @brief  Low layer CNT value = CMP value interrupt disable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_cnt_cmp_interrupt_disable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_IE &= (~LL_TIMER_IE_CNT_CMP_IE);
}

/**
  * @brief  Low layer CNT value = PRD value interrupt enable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_cnt_prd_interrupt_enable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_IE |= LL_TIMER_IE_CNT_PRD_IE;
}

/**
  * @brief  Low layer CNT value = PRD value interrupt disable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_cnt_prd_interrupt_disable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_IE &= (~LL_TIMER_IE_CNT_PRD_IE);
}

/**
  * @brief  Low layer CNT value overflows interrupt enable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_cnt_overflow_interrupt_enable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_IE |= LL_TIMER_IE_CNT_OVERFLOW_IE;
}

/**
  * @brief  Low layer CNT value overflows interrupt disable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_cnt_overflow_interrupt_disable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_IE &= (~LL_TIMER_IE_CNT_OVERFLOW_IE);
}

/**
  * @brief  Low layer capture event 2 occurs interrupt enable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_capture2_interrupt_enable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_IE |= LL_TIMER_IE_CAPTURE2_IE;
}

/**
  * @brief  Low layer capture event 2 occurs interrupt disable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_capture2_interrupt_disable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_IE &= (~LL_TIMER_IE_CAPTURE2_IE);
}

/**
  * @brief  Low layer capture event 1 occurs interrupt enable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_capture1_interrupt_enable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_IE |= LL_TIMER_IE_CAPTURE1_IE;
}

/**
  * @brief  Low layer capture event 1 occurs interrupt disable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_capture1_interrupt_disable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_IE &= (~LL_TIMER_IE_CAPTURE1_IE);
}


/**
  * @brief  TIMERx polarity reversed enabled function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_pwm_pol_enable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_CON |= LL_TIMER_CON_PWM_POL;
}

/**
  * @brief  TIMERx  polarity reversed disable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_pwm_pol_disable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_CON &= (~LL_TIMER_CON_PWM_POL);
}
/**
  * @brief  TIMERx  gate kepp enable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_gate_keep_enable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_CON |= LL_TIMER_CON_GATE_KEEP_MODE_SEL;
}

/**
  * @brief  TIMERx  gate kepp disable function
  * @param  p_timer  : Structure pointer set to TIMERx
  * @retval None
  */
void ll_timer_gate_keep_disable(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_CON &= (~LL_TIMER_CON_GATE_KEEP_MODE_SEL);
}


/**
  * @brief  timer pwm mode config
  * @param  p_timer : Structure pointer set to TIMERx
  * @param  freq_hz : PWM frequency
  * @param  duty_per : PWM duty cycle
  * @retval None  
  */
void ll_timer_pwm_config(TIMER_TypeDef *p_timer, u32 freq_hz, u8 duty_per)
{
    u8 psc_index = 0;
    u32 tmr_con = p_timer->TMR_CON;
    u32 rc_reg_value = (((*((u32 *)TIME_TRIM_ADDR)) >> 16)>>2) & 0x2FFF;    //read ic time trimming actual value

    u32 period_cnt = 0;
    u32 duty_cnt = 0;
    
    if(rc_reg_value > 12017 || rc_reg_value < 11985)
    {
        rc_reg_value = 12000;
    }
    
    if((freq_hz>=10)&&(freq_hz<100)){
        psc_index = LL_TIMER_PSC_128;
    }else if((freq_hz>=100)&&(freq_hz<1000)){
        psc_index = LL_TIMER_PSC_32;
    }else if((freq_hz>=1000)&&(freq_hz<=1000000)){
        psc_index = LL_TIMER_PSC_2;
    }else{
        return;
    }
    tmr_con = (tmr_con & (~LL_TIMER_CON_DIVISION_SET(ALL_WORD_FF))) | LL_TIMER_CON_DIVISION_SET(psc_index);
    tmr_con = (tmr_con & (~LL_TIMER_CON_SRC_SEL(ALL_WORD_FF))) | LL_TIMER_CON_SRC_SEL(LL_TIMER_SRC_SYS_RISING);
    tmr_con = (tmr_con & (~LL_TIMER_CON_MODE_SET(ALL_WORD_FF))) | LL_TIMER_CON_MODE_SET(LL_TIMER_MODE_SEL_PWM);
    p_timer->TMR_CON = tmr_con;
    p_timer->TMR_CNT  = 0;
    
    if(duty_per>99){
        duty_per = 100;
    }
    
    switch((SYSCTRL->CLK_CON3>>10) & 0x3)  //Deter HIRC selection .note:time clk source is 2 division of hirc. 
    {
        case 0x0: //12Mhz fator:2
            period_cnt = ((rc_reg_value*1000*2)>>psc_index)/freq_hz;   //period_cnt = target_freq(hz) / set_freq(hz)
            break;
        case 0x1: //16Mhz fator:8/3
            period_cnt = ((rc_reg_value*1000*8/3)>>psc_index)/freq_hz;   //period_cnt = target_freq(hz) / set_freq(hz)
            break;
        case 0x2: //18Mhz fator:3
            period_cnt = ((rc_reg_value*1000*3)>>(psc_index))/freq_hz;   //period_cnt = target_freq(hz) / set_freq(hz)
            break;
        case 0x3: //24Mhz fator:4
            period_cnt = ((rc_reg_value*1000*4)>>psc_index)/freq_hz;   //period_cnt = target_freq(hz) / set_freq(hz)
            break;
        default:
            break;
    }
    duty_cnt  = (duty_per * period_cnt)/100;
    p_timer->TMR_CAP3 = duty_cnt<<16 | period_cnt;
}

/**
  * @brief  timer pwm mode config extend
  * @param  p_timer : Structure pointer set to TIMERx
  * @param  freq_hz : PWM frequency
  * @param  duty_per : PWM duty cycle
  * @retval None  
  */
void ll_timer_pwm_config_ex(TIMER_TypeDef *p_timer, u32 freq_hz, u8 duty_per, TYPE_ENUM_LL_TIMER_PWM_ACTIVE_LEVEL_SEL active_level)
{
    
    u8 psc_index = 0;
    u32 tmr_con = p_timer->TMR_CON;
    u32 rc_reg_value = (((*((u32 *)TIME_TRIM_ADDR)) >> 16)>>2) & 0x2FFF;    //read ic time trimming actual value
    u32 period_cnt = 0;
    u32 duty_cnt = 0;
    
    if(rc_reg_value > 12017 || rc_reg_value < 11985)
    {
        rc_reg_value = 12000;
    }
    
    if((freq_hz>=10)&&(freq_hz<100)){
        psc_index = LL_TIMER_PSC_128;
    }else if((freq_hz>=100)&&(freq_hz<1000)){
        psc_index = LL_TIMER_PSC_32;
    }else if((freq_hz>=1000)&&(freq_hz<=1000000)){
        psc_index = LL_TIMER_PSC_2;
    }else{
        return;
    }
    tmr_con = (tmr_con & (~LL_TIMER_CON_DIVISION_SET(ALL_WORD_FF))) | LL_TIMER_CON_DIVISION_SET(psc_index);
    tmr_con = (tmr_con & (~LL_TIMER_CON_SRC_SEL(ALL_WORD_FF))) | LL_TIMER_CON_SRC_SEL(LL_TIMER_SRC_SYS_RISING);
    tmr_con = (tmr_con & (~LL_TIMER_CON_MODE_SET(ALL_WORD_FF))) | LL_TIMER_CON_MODE_SET(LL_TIMER_MODE_SEL_PWM);
    if(active_level == LL_TIMER_PWM_ACTIVE_LEVEL_L)
    {
        tmr_con |= LL_TIMER_CON_PWM_POL;
    }
    else
    {
        tmr_con &= ~LL_TIMER_CON_PWM_POL;
    }
    p_timer->TMR_CON = tmr_con;
    p_timer->TMR_CNT  = 0;
    
    if(duty_per>99){
        duty_per = 100;
    }
    
    switch((SYSCTRL->CLK_CON3>>10) & 0x3)  //Deter HIRC selection
    {
        case 0x0: //12Mhz fator:2
            period_cnt = ((rc_reg_value*1000*2)>>psc_index)/freq_hz;   //period_cnt = target_freq(hz) / set_freq(hz)
            break;
        case 0x1: //16Mhz fator:8/3
            period_cnt = ((rc_reg_value*1000*8/3)>>psc_index)/freq_hz;   //period_cnt = target_freq(hz) / set_freq(hz)
            break;
        case 0x2: //18Mhz fator:3
            period_cnt = ((rc_reg_value*1000*3)>>(psc_index))/freq_hz;   //period_cnt = target_freq(hz) / set_freq(hz)
            break;
        case 0x3: //24Mhz fator:4
            period_cnt = ((rc_reg_value*1000*4)>>psc_index)/freq_hz;   //period_cnt = target_freq(hz) / set_freq(hz)
            break;
        default:
            break;
    }
    duty_cnt  = (duty_per * period_cnt)/100;
    p_timer->TMR_CAP3 = duty_cnt<<16 | period_cnt;
}

/**
  * @brief  timer pwm duty fixed
  * @param  p_timer : Structure pointer set to TIMERx
  * @param  duty_per : PWM duty cycle
  * @retval None  
  */
void ll_timer_pwm_duty_fixed(TIMER_TypeDef *p_timer, u8 duty_per)
{
    if(duty_per>99)
        duty_per = 100;
    p_timer->TMR_CAP3 = (p_timer->TMR_CAP1*duty_per/100)<<16 | p_timer->TMR_CAP1;
}

/**
  * @brief  timer pwm mode start
  * @param  p_timer  :   Structure pointer set to TIMERx
  * @retval None  
  */
void ll_timer_pwm_start(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_CON = (p_timer->TMR_CON & (~LL_TIMER_CON_MODE_SET(ALL_WORD_FF))) | LL_TIMER_CON_MODE_SET(LL_TIMER_MODE_SEL_PWM);
    p_timer->TMR_CLR |= LL_TIMER_CLR_ALL_PENDING;
    p_timer->TMR_EN |= LL_TIMER_EN;
}

/**
  * @brief  timer pwm mode stop
  * @param  p_timer  :   Structure pointer set to TIMERx
  * @note   
  * @retval None  
  */
void ll_timer_pwm_stop(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_CLR |= LL_TIMER_CLR_ALL_PENDING;
    p_timer->TMR_EN &= ~LL_TIMER_EN;
} 

/**
  * @brief  timer count mode to set time
  * @param  p_timer : Structure pointer set to TIMERx, 
  * @param  value_us:timing time(us)
  * @note   
  * @retval None  
  */
void ll_timer_cnt_set_us(TIMER_TypeDef *p_timer, u32 value_us)
{
    u32 tmr_con;
    u32 rc_reg_value = (((*((u32 *)TIME_TRIM_ADDR)) >> 16)>>2 ) & 0x2FFF;   //read ic time trimming actual value
    u8 psc_index = 0;
    
    if(rc_reg_value > 12017 || rc_reg_value < 11985)
    {
        rc_reg_value = 12000;
    }
    
    if(0==(SYSCTRL->CLK_CON0 & 0x3))
    {
        return;
    }
    
    //由于校准频率采用12Mhz
    
    if(value_us < 1000){             //1ms
        psc_index = LL_TIMER_PSC_2;
    }else if(value_us < 10000){      //10ms
       psc_index = LL_TIMER_PSC_32;
    }else if(value_us < 100001){     //100ms
       psc_index = LL_TIMER_PSC_128;
    }else{
        return;
    }

    if((value_us > 0)&&(value_us < 100001)){
        tmr_con = p_timer->TMR_CON;
        tmr_con = (tmr_con & (~LL_TIMER_CON_DIVISION_SET(ALL_WORD_FF))) | LL_TIMER_CON_DIVISION_SET(psc_index);
        tmr_con = (tmr_con & (~LL_TIMER_CON_SRC_SEL(ALL_WORD_FF))) | LL_TIMER_CON_SRC_SEL(LL_TIMER_SRC_SYS_RISING);
        tmr_con = (tmr_con & (~LL_TIMER_CON_MODE_SET(ALL_WORD_FF))) | LL_TIMER_CON_MODE_SET(LL_TIMER_MODE_SEL_COUNTER);
        p_timer->TMR_CON = tmr_con;
        p_timer->TMR_CNT  = 0;
        switch((SYSCTRL->CLK_CON3>>10) & 0x3)  //Deter HIRC selection
        {
            case 0x0: //12Mhz fator:2
                p_timer->TMR_CAP1   = (((rc_reg_value * value_us * 2)>>psc_index)/1000);   //value = freq(Mhz) * time(us)
                break;
            case 0x1: //16Mhz fator:8/3
                p_timer->TMR_CAP1   = (((rc_reg_value * value_us * 8 / 3)>>psc_index)/1000);   //value = freq(Mhz) * time(us)
                break;
            case 0x2: //18Mhz fator:3
                p_timer->TMR_CAP1   = (((rc_reg_value * value_us * 3)>>(psc_index))/1000);   //value = freq(Mhz) * time(us)
                break;
            case 0x3: //24Mhz fator:4
                p_timer->TMR_CAP1   = (((rc_reg_value * value_us * 4)>>psc_index)/1000);   //value = freq(Mhz) * time(us)
                break;
            default:
                break;
        }
        p_timer->TMR_IE |= LL_TIMER_IE_CNT_PRD_IE;    //enable irq
    }
}


/**
  * @brief  timer count mode start
  * @param  p_timer  :   Structure pointer set to TIMERx
  * @note   
  * @retval None  
  */
void ll_timer_cnt_start(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_CON = (p_timer->TMR_CON & (~LL_TIMER_CON_MODE_SET(ALL_WORD_FF))) | LL_TIMER_CON_MODE_SET(LL_TIMER_MODE_SEL_COUNTER);
    p_timer->TMR_CLR |= LL_TIMER_CLR_ALL_PENDING;
    p_timer->TMR_EN |= LL_TIMER_EN;
}

/**
  * @brief  timer count mode stop
  * @param  p_timer  :   Structure pointer set to TIMERx
  * @note   
  * @retval None  
  */
void ll_timer_cnt_stop(TIMER_TypeDef *p_timer)
{
    p_timer->TMR_CLR |= LL_TIMER_CLR_ALL_PENDING;
    p_timer->TMR_EN &= ~LL_TIMER_EN;
}


/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

/*************************** (C) COPYRIGHT 2022 JUSHENG ***** END OF FILE *****/
